package com.wang.gallerybackend.manager.upload;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.ciModel.persistence.CIObject;
import com.qcloud.cos.model.ciModel.persistence.ImageInfo;
import com.qcloud.cos.model.ciModel.persistence.ProcessResults;
import com.wang.gallerybackend.config.CosClientConfig;
import com.wang.gallerybackend.exception.BusinessException;
import com.wang.gallerybackend.exception.ErrorCode;
import com.wang.gallerybackend.manager.CosManager;
import com.wang.gallerybackend.model.dto.file.UploadPictureResult;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * 图片上传模板
 */
@Slf4j
public abstract class PictureUpload {
	@Resource
	private CosClientConfig cosClientConfig;
	@Resource
	private CosManager cosManager;
	//允许文件上传的文件列表
	final List<String> ALLOW_FILE_SUFFIX = List.of("png", "jpg", "jpeg", "gif", "webp");
	final long MAXSIZE = 1024 * 1024 * 2;

	/**
	 * 上传图片
	 * @param inputSource
	 * @param uploadPathPrefix
	 * @return
	 */
	public UploadPictureResult uploadPicture(Object inputSource, String uploadPathPrefix) {
		//校验图片
		validPicture(inputSource);
		//图片上传地址
		String uuid = RandomUtil.randomString(16);
		String originalFilename = getOriginalFilename(inputSource);
		//自己拼接文件名
		String uploadFileName = String.format("%s_%s.%s", DateUtil.formatDate(new Date()),
				uuid, FileUtil.getSuffix(originalFilename));
		String uploadPath = String.format("/%s/%s", uploadPathPrefix, uploadFileName);
		//解析结果并返回
		File file = null;
		try {
			file = File.createTempFile(uploadPath, null);
			//处理文件来源
			processFile(inputSource, file);
			PutObjectResult putObjectResult = cosManager.putPictureObject(uploadPath, file);
			//获取图片信息对象
			ImageInfo imageInfo = putObjectResult.getCiUploadResult().getOriginalInfo().getImageInfo();
			//获取到图片处理结果
			ProcessResults processResults = putObjectResult.getCiUploadResult().getProcessResults();
			List<CIObject> objectList = processResults.getObjectList();
			if (CollUtil.isNotEmpty(objectList)) {
				//获取压缩之后得到的文件信息
				CIObject compressObject = objectList.get(0);
				CIObject ciObject = compressObject;
				//有生成缩略图，才获取缩略图
				if (objectList.size() > 1) {
					//封装缩略图结果
					ciObject = objectList.get(1);
				}
				//封装压缩图结果
				return getUploadPictureResult(originalFilename, compressObject, ciObject, imageInfo);
			}
			return getUploadPictureResult(imageInfo, uploadPath, originalFilename, file);
		} catch (IOException e) {
			throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传失败");
		} finally {
			//临时文件清理
			deleteTemFile(file);
		}


	}

	/**
	 * 获取上传图片结果
	 * @param originalFilename 原始文件名
	 * @param compressObject 压缩后的对象
	 * @param ciObject 缩略图对象
	 * @param imageInfo 图片信息对象
	 * @return
	 */
	private UploadPictureResult getUploadPictureResult(String originalFilename, CIObject compressObject, CIObject ciObject
			, ImageInfo imageInfo) {
		//封装结果
		int picWidth = compressObject.getWidth();
		int picHeight = compressObject.getHeight();
		double picScale = NumberUtil.round(picWidth * 1.0 / picHeight, 2).doubleValue();
		UploadPictureResult uploadPictureResult = new UploadPictureResult();
		//设置原图地址
		uploadPictureResult.setUrl(cosClientConfig.getHost() + '/' + compressObject.getKey());
		uploadPictureResult.setName(FileUtil.mainName(originalFilename));
		uploadPictureResult.setPicSize(compressObject.getSize().longValue());
		uploadPictureResult.setPicWidth(picWidth);
		uploadPictureResult.setPicHeight(picHeight);
		uploadPictureResult.setPicScale(picScale);
		uploadPictureResult.setPicFormat(compressObject.getFormat());
		uploadPictureResult.setPicColor(imageInfo.getAve());
		//封装缩略图结果
		uploadPictureResult.setThumbnailUrl(cosClientConfig.getHost() + '/' + ciObject.getKey());
		//返回结果
		return uploadPictureResult;
	}

	/**
	 * 获取上传图片结果
	 *
	 * @param imageInfo 图片信息对象
	 * @param uploadPath
	 * @param originalFilename
	 * @param file
	 * @return
	 */
	private UploadPictureResult getUploadPictureResult(ImageInfo imageInfo, String uploadPath, String originalFilename, File file) {
		//封装结果
		int picWidth = imageInfo.getWidth();
		int picHeight = imageInfo.getHeight();
		double picScale = NumberUtil.round(picWidth * 1.0 / picHeight, 2).doubleValue();
		UploadPictureResult uploadPictureResult = new UploadPictureResult();
		uploadPictureResult.setUrl(cosClientConfig.getHost() + '/' + uploadPath);
		uploadPictureResult.setName(FileUtil.mainName(originalFilename));
		uploadPictureResult.setPicSize(FileUtil.size(file));
		uploadPictureResult.setPicWidth(picWidth);
		uploadPictureResult.setPicHeight(picHeight);
		uploadPictureResult.setPicScale(picScale);
		uploadPictureResult.setPicFormat(imageInfo.getFormat());
		uploadPictureResult.setPicColor(imageInfo.getAve());
		//返回结果
		return uploadPictureResult;
	}

	/**
	 * 处理文件来源
	 * @param inputSource
	 */
	protected abstract void processFile(Object inputSource, File file) throws IOException;

	/**
	 *  获取原始文件名
	 * @param inputSource
	 * @return
	 */
	protected abstract String getOriginalFilename(Object inputSource);

	/**
	 *  校验图片
	 * @param inputSource
	 */
	protected abstract void validPicture(Object inputSource);

	/**
	 * 删除临时文件
	 * @param file
	 */
	public static void deleteTemFile(File file) {
		if (file != null) {
			//删除临时文件
			boolean deleteResult = file.delete();
			if (!deleteResult) {
				log.error("文件删除失败 = {}", file.getAbsolutePath());
			}
		}
	}

}
